/**
 * By Alpha
 * Author: alixez <alixe.z@foxmail.com>
 * Date: 2017/11/3
 */

/* global window */

import React, { Component } from 'react';
import NProgress from 'nprogress';
import PropTypes from 'prop-types';
import pathToRegexp from 'path-to-regexp';
import { connect } from 'dva';
import { Layout, Loader } from 'components';
import { classNames, config } from 'utils';
import { Helmet } from 'react-helmet';
import { withRouter } from 'dva/router';
// import 'ant-design-pro/dist/ant-design-pro.css';
import '../themes/index.less';
import './app.less';
import Error from './error';

const { prefix, openPages } = config;
const { Header, Bread, Footer, Sider, styles } = Layout;

let loadLocationHref = null;

class App extends Component {
  static propTypes = {
    children: PropTypes.element.isRequired,
    location: PropTypes.object,
    dispatch: PropTypes.func,
    app: PropTypes.object,
    loading: PropTypes.object,
  };

  render () {
    const { children, dispatch, app, loading, location } = this.props;
    const { user, sideFold, darkTheme, isNavBar, menuPopoverVisible, navOpenKeys, menu, permissions } = app;
    let { pathname } = location;
    pathname = pathname.startsWith('/') ? pathname : `/${pathname}`;
    const { iconFontJS, iconFontCSS, logo } = config;
    const current = menu.filter(item => pathToRegexp(item.route || '').exec(pathname));
    const hasPermission = current.length ? permissions.visit.includes(current[0].id) : false;

    const href = window.location.href;

    if (loadLocationHref !== href) {
      NProgress.start();
      if (!loading.global) {
        NProgress.done();
        loadLocationHref = href;
      }
    }

    const headerProps = {
      menu,
      user,
      location,
      sideFold,
      isNavBar,
      menuPopoverVisible,
      navOpenKeys,
      switchMenuPopover () {
        dispatch({ type: 'app/toggleMenuPopover' });
      },
      logout () {
        dispatch({ type: 'app/logout' });
      },
      switchSide () {
        dispatch({ type: 'app/toggleSideArea' });
      },
      changeOpenKeys (openKeys) {
        dispatch({ type: 'app/handleNavOpenKeys', payload: { navOpenKeys: openKeys } });
      },
    };

    const sideProps = {
      menu,
      location,
      sideFold,
      darkTheme,
      navOpenKeys,
      changeTheme () {
        dispatch({ type: 'app/toggleTheme' });
      },
      changeOpenKeys (openKeys) {
        window.localStorage.setItem(`${prefix}navOpenKeys`, JSON.stringify(openKeys));
        dispatch({ type: 'app/handleNavOpenKeys', payload: { navOpenKeys: openKeys } });
      },
    };

    const breadProps = {
      menu,
      location,
    };
    if (openPages && openPages.includes(pathname)) {
      return (<div>
        <Loader fullScreen spinning={loading.effects['app/query']} />
        {children}
      </div>);
    }
    return (
      <div>
        <Loader fullScreen spinning={loading.effects['app/query']} />
        <Helmet>
          <title>UNITE | 为了爱和美好 </title>
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <link rel="icon" href={logo} type="image/x-icon" />
          {iconFontJS && <script src={iconFontJS} />}
          {iconFontCSS && <link rel="stylesheet" href={iconFontCSS} />}
        </Helmet>
        <div className={classNames(styles.layout, { [styles.fold]: isNavBar ? false : sideFold }, { [styles.withnavbar]: isNavBar })}>
          {!isNavBar ? <aside className={classNames(styles.sider, { [styles.light]: !darkTheme })}>
            {sideProps.menu.length === 0 ? null : <Sider {...sideProps} />}
          </aside> : ''}
          <div className={styles.main}>
            <Header {...headerProps} />
            <Bread {...breadProps} />
            <div className={styles.container}>
              <div className={styles.content}>
                {hasPermission ? children : children}
              </div>
            </div>
            <Footer />
          </div>
        </div>
      </div>
    );
  }
}

export default withRouter(connect(({ app, loading }) => ({ app, loading }))(App));
